﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.IO;
using System.Xml.Serialization;
using System.Xml;

namespace eVision.SharpSort
{
    public class Serializer
    {
        private static XmlSerializerNamespaces nsForSerialization = null;

        static Serializer()
        {
            nsForSerialization =  new XmlSerializerNamespaces();
            nsForSerialization.Add("", "");
        }

        public static String XmlSerialize<TValue>(TValue value)
        {
            return XmlSerialize<TValue>(value, false, false);
        }

        public static String XmlSerialize<TValue>(TValue value, bool writeXmlDeclaration, bool indent)
        {
            XmlSerializer xs = new XmlSerializer(typeof(TValue));
            XmlWriterSettings settings = new XmlWriterSettings();

            settings.OmitXmlDeclaration = !writeXmlDeclaration;
            settings.Indent = indent;
            StringBuilder sb = new StringBuilder();

            using (StringWriter sw = new StringWriter(sb))
            {
                using (XmlWriter xmlw = XmlWriter.Create(sw, settings))
                {
                    xs.Serialize(xmlw, value, nsForSerialization);

                    xmlw.Flush();
                    sw.Flush();

                    return sb.ToString();
                }
            }
        }

        public static byte[] BinarySerialize<TValue>(TValue value)
        {
            IFormatter formatter = new BinaryFormatter();
            byte[] result = null;
            using (Stream stream = new MemoryStream())
            {
                formatter.Serialize(stream, value);

                result = new byte[stream.Length];
                stream.Position = 0;
                stream.Read(result, 0, result.Length);

                stream.Flush();
                stream.Close();

                return result;
            }
        }

        public static TValue XmlDeserialize<TValue>(String data)
        {
            XmlSerializer xs = new XmlSerializer(typeof(TValue));
            StringReader sr = new StringReader(data);

            return (TValue)xs.Deserialize(sr);
        }

        public static Object XmlDeserialize(Type typeToDeserialize, String data)
        {
            XmlSerializer xs = new XmlSerializer(typeToDeserialize);
            StringReader sr = new StringReader(data);

            return xs.Deserialize(sr);
        }

        public static TValue BinaryDeserialize<TValue>(byte[] data)
        {
            IFormatter formatter = new BinaryFormatter();
            using (Stream stream = new MemoryStream(data))
            {
                return (TValue)formatter.Deserialize(stream);
            }
        }

        public static String BinarySerializeToString<TValue>(TValue value)
        {
            return Convert.ToBase64String(BinarySerialize<TValue>(value));
        }

        public static TValue BinaryDeserializeFromString<TValue>(String data)
        {
            return BinaryDeserialize<TValue>(Convert.FromBase64String(data));
        }
    }
}
